/*
 * =====================================================================================
 *
 *       Filename:  flash_upload_stream_request.cc
 *
 *    Description:  
 *
 *        Version:  1.0
 *        Created:  2013年06月24日 10时50分42秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Xie Yanping (), 
 *        Company:  www.Qihoo.net
 *
 * =====================================================================================
 */

#include <time.h>
#include <sstream>
#include <iomanip>
#include <openssl/md5.h>
#include <boost/format.hpp>
#include <boost/algorithm/string.hpp>
#include "redis_executor/redis_executor.h"
#include "redis_executor/redis_locator.h"
#include "redis_executor/scoped_reply.h"
#include "flash_upload_stream_request.h"
#include "file_trans_redis.h"
#include "base/logging.h"

namespace imserver {
namespace fcgi {

//extern std::map<std::string, std::string> gFCTypes;
extern std::string CalculateFileIdentify(const FileContent& c);
extern void ParseFileContent(FileContent& content,
                             std::string& body,
                             std::string& callback,
                             const std::string& spliter);

bool FileTransFlashUpstreamRequest::Response() {
  LOG_DEBUG("[FileTransUpstreamRequest::Response] called.");
  if (!fcgi_out_) {
    LOG_ERROR("Fast-cgi for upload stream of file transfer is NULL.");
    return false;
  }

  //get boundary
  std::string boundary;
  std::string pattern = "boundary=";
  std::string content_type = GetParam("CONTENT_TYPE");
  std::string::size_type p = content_type.find(pattern);
  if (p != std::string::npos) {
    boundary = content_type.substr(p + pattern.size());
    boundary = "--" + boundary;
  }
  LOG_DEBUG("boundary=" << boundary);

  std::string rsp_header("Content-type: text/javascript; charset=utf-8\r\n\r\n");
  FCGX_PutS(rsp_header.c_str(), fcgi_out_);
  // read line until get the content-type and content-length
  FileContent content;
  std::string callback;
  ParseFileContent(content, body_, callback, boundary);
  if (content.content_length > 1024 * 1024 * 10) {
    std::string rsp_header(
        "HTTP/1.1 400 Bad Request\r\n"
        "Content-type: text/html\r\n"
        "Content-Length: 0\r\n\r\n");
    FCGX_PutS(rsp_header.c_str(), fcgi_out_);
    return false;
  }
  // file content
/*  std::string ext = content.name.substr(content.name.find_last_of('.'));
  boost::to_lower(ext);
  std::map<std::string, std::string>::iterator it = gFCTypes.find(ext);
  if (it != gFCTypes.end()) {
    content.content_type = it->second;*/
  {
    content.timestamp    = time(NULL);
    content.identify     = CalculateFileIdentify(content);

    boost::format fmt(
        "{\"errno\":%1%,"
        "\"name\":\"%2%\","
        "\"src\":\"http://f.im.bang.360.cn/ft/d?fid=%3%\"}");
    for (int i=0; i<3; i++) {
      if (0 == FileTransRedis::GetInst().SetFileContent(content) &&
          0 == FileTransRedis::GetInst().SetFileStream(body_, content.identify)) {
        LOG_INFO("SetFile succeed.(file=" << content.name
            << " length=" << content.content_length
            << " type=" << content.content_type
            << " identify=" << content.identify << ")");
        fmt % 0 % content.name % content.identify;
        FCGX_PutS(fmt.str().c_str(), fcgi_out_);
        return true;
      } else {
        LOG_WARN("SetFile retry - " << i << ".(file=" << content.name << ")");
      }
    }

    LOG_ERROR("SetFile failed.(file=" << content.name
        << " length=" << content.content_length
        << " type=" << content.content_type
        << " identify=" << content.identify << ")");
    fmt % 1 % content.name % content.identify;
    FCGX_PutS(fmt.str().c_str(), fcgi_out_);
    return false;
  }
  return true;
}

}
}
